# Compiler settings
CC = gcc
CFLAGS = -Wall -Wextra -std=c99 -O2
LDFLAGS = -lnanomsg -lpthread

# Debug settings
ifdef DEBUG
    CFLAGS += -g -DDEBUG
endif

# Optimization settings
ifdef OPTIMIZE
    CFLAGS += -O3 -march=native
endif

# Nanomsg prefix (if installed in non-standard location)
ifdef NANOMSG_PREFIX
    CFLAGS += -I$(NANOMSG_PREFIX)/include
    LDFLAGS += -L$(NANOMSG_PREFIX)/lib
endif

# Directories
SRCDIR = src
BINDIR = bin
OBJDIR = obj

# Source files
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)

# Executables (excluding common.c)
EXECUTABLES = simple_pair reqrep_server reqrep_client pubsub_publisher pubsub_subscriber pipeline_push pipeline_pull

# Targets
TARGETS = $(addprefix $(BINDIR)/, $(EXECUTABLES))

# Default target
all: directories $(TARGETS)

# Create directories
directories:
	@mkdir -p $(BINDIR) $(OBJDIR)

# Pattern rule for object files
$(OBJDIR)/%.o: $(SRCDIR)/%.c
	@echo "Compiling $<..."
	$(CC) $(CFLAGS) -c $< -o $@

# Individual executable targets
$(BINDIR)/simple_pair: $(OBJDIR)/simple_pair.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

$(BINDIR)/reqrep_server: $(OBJDIR)/reqrep_server.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

$(BINDIR)/reqrep_client: $(OBJDIR)/reqrep_client.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

$(BINDIR)/pubsub_publisher: $(OBJDIR)/pubsub_publisher.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

$(BINDIR)/pubsub_subscriber: $(OBJDIR)/pubsub_subscriber.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

$(BINDIR)/pipeline_push: $(OBJDIR)/pipeline_push.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

$(BINDIR)/pipeline_pull: $(OBJDIR)/pipeline_pull.o
	@echo "Linking $@..."
	$(CC) $^ -o $@ $(LDFLAGS)

# Group targets for convenience
simple_pair: $(BINDIR)/simple_pair

reqrep: $(BINDIR)/reqrep_server $(BINDIR)/reqrep_client

pubsub: $(BINDIR)/pubsub_publisher $(BINDIR)/pubsub_subscriber

pipeline: $(BINDIR)/pipeline_push $(BINDIR)/pipeline_pull

# Test targets
test: all
	@echo "Running nanomsg tests..."
	@./test/run_tests.sh

# Check nanomsg installation
check-deps:
	@echo "Checking nanomsg installation..."
	@pkg-config --exists nanomsg && echo "✓ nanomsg found" || echo "✗ nanomsg not found"
	@echo "nanomsg version: $$(pkg-config --modversion nanomsg 2>/dev/null || echo 'unknown')"
	@echo "nanomsg cflags: $$(pkg-config --cflags nanomsg 2>/dev/null || echo 'not available')"
	@echo "nanomsg libs: $$(pkg-config --libs nanomsg 2>/dev/null || echo 'not available')"

# Install targets (if needed)
install: all
	@echo "Installing binaries to /usr/local/bin..."
	@sudo cp $(TARGETS) /usr/local/bin/
	@echo "Installation complete."

uninstall:
	@echo "Removing installed binaries..."
	@for target in $(EXECUTABLES); do \
		sudo rm -f /usr/local/bin/$$target; \
	done
	@echo "Uninstallation complete."

# Clean targets
clean:
	@echo "Cleaning build files..."
	@rm -rf $(OBJDIR) $(BINDIR)
	@echo "Clean complete."

clean-all: clean
	@echo "Removing all generated files..."
	@rm -f *.log *.tmp core.*

# Documentation
docs:
	@echo "Generating documentation..."
	@doxygen Doxyfile 2>/dev/null || echo "Doxygen not found, skipping documentation generation"

# Format code
format:
	@echo "Formatting source code..."
	@find $(SRCDIR) -name "*.c" -o -name "*.h" | xargs clang-format -i

# Static analysis
analyze:
	@echo "Running static analysis..."
	@cppcheck --enable=all --std=c99 $(SRCDIR)/ 2>/dev/null || echo "cppcheck not found, skipping analysis"

# Memory check (requires valgrind)
memcheck: $(BINDIR)/simple_pair
	@echo "Running memory check..."
	@valgrind --leak-check=full --show-leak-kinds=all ./$(BINDIR)/simple_pair node1 2>/dev/null || echo "valgrind not found, skipping memory check"

# Performance benchmark
benchmark: all
	@echo "Running performance benchmarks..."
	@./scripts/benchmark.sh 2>/dev/null || echo "Benchmark script not found"

# Show build information
info:
	@echo "Build Information:"
	@echo "=================="
	@echo "CC: $(CC)"
	@echo "CFLAGS: $(CFLAGS)"
	@echo "LDFLAGS: $(LDFLAGS)"
	@echo "SRCDIR: $(SRCDIR)"
	@echo "BINDIR: $(BINDIR)"
	@echo "OBJDIR: $(OBJDIR)"
	@echo "TARGETS: $(TARGETS)"
	@echo ""
	@echo "Available targets:"
	@echo "  all       - Build all executables"
	@echo "  clean     - Remove build files"
	@echo "  test      - Run tests"
	@echo "  install   - Install to system"
	@echo "  docs      - Generate documentation"
	@echo "  format    - Format source code"
	@echo "  analyze   - Run static analysis"
	@echo "  memcheck  - Run memory checks"
	@echo "  benchmark - Run performance tests"
	@echo "  info      - Show this information"

# Help target
help: info

# Phony targets
.PHONY: all directories clean clean-all test check-deps install uninstall docs format analyze memcheck benchmark info help simple_pair reqrep pubsub pipeline

# Dependencies
-include $(OBJECTS:.o=.d)

# Generate dependency files
$(OBJDIR)/%.d: $(SRCDIR)/%.c
	@set -e; rm -f $@; \
	$(CC) -MM $(CFLAGS) $< > $@.$$$$; \
	sed 's,\($*\)\.o[ :]*,$(OBJDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$